#!/sbin/bash
# Copyright (c) 2010 Andre Sencioles Vitorio Oliveira <andre@bcp.net.br>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

### Miletools ###
# Script auxiliar de configuracao para o Motorola(r) Milestone
# Versao 0.5

### Changelog ###
# 0.5
#  * Inclusao do menu de backup de aplicacoes
#  * Corrigidas as referencias ao nome do script
#  * Adicionada a versão na entrada do menu
#  * Melhorias na exibicao do espaco livre
#  * Memhack modificado para utilizar mount conforme sugerido pelo Edgard
#  * Removida a opcao de instalacao de file manager (substituida pelo menu de backup)
#
# 0.4
#  * Adicionada opcao de instalar um file manager - by Thiago Motta
#
# 0.3
#  * Mapa do menu
#  * Mudança de escrutura para OR/app
#  * Exibe o espaco livre nas particoes no menu principal.
#  * Inclusao da menu de Backup.
#  * Inclusao da opcao para remover o OpenRecovery da Galeria.
#  * Inclusao da opcao para ativar o multitouch distinto.
#  * Inclusao do menu de governors.
#
# 0.2
#  * Versionamento e ChangeLog.
#  * Inclusao da opção Memhack para a nova versao do ShadowMOD-BR (0.9.14).
#
# 0.1
#  * Versao inicial.

### Mapa do menu ###
# Milestone Tools 0.5
# |- *** Espaco Livre ***
# |- /cache ??Mb (??% em uso)
# |- /data ??Mb (??% em uso)
# |- /system ??Mb (??% em uso)
# |- *** Submenus ***
# |+ Backup
#  |- Voltar
#  |- *** build.prop ***
#  |- Efetuar backup
#  |+ Restaurar backup
#   |- Voltar
#   |- 02-02-2002 02.02
#   |- 02-02-2002 02.01
#   |- (...)
#  |- *** Aplicativos ***
#  |+ Efetuar backup
#   |- Voltar
#   |- *** Dir 1 ***
#   |- App1
#   |- App2
#   |- (...)
#   |- Voltar
#  |+ Restaurar backup
#   |- Voltar
#   |- *** Dir 1 ***
#   |- App2
#   |- App3
#   |- (...)
#   |- Voltar
# |+ Ajustar DPI da tela
#  |- Voltar
#  |- 180
#  |- 190 (Menor recomendavel)
#  |- (...)
# |+ Selecionar Governor
#  |- Voltar
#  |- *** Governors habilitados ***
#  |- stats (Estatisticas Time-in-state)
#  |- conservative (Maior economia)
#  |- interactive (maior performance)
#  |- (...)
#  |- *** Governor padrao ***
#  |- conservative
#  |- interactive
#  |- (...)
# |- *** Opcoes ***
# |- Manter aplicativo Home sempre na memoria
# |- Mover Dalvik-Cache para /cache
# |- Problemas com DNS
# |- Remover OpenRecovery da Galeria de Imagens


### Declaracao de variaveis e funcoes ###

# Internal Field Separator
OLDIFS="${IFS}"
export IFS='
'

# Diretorio principal
export MILETOOLS_ROOT='/sdcard/.miletools'

# Diretorio de backups
export MILETOOLS_BKPS="${MILETOOLS_ROOT}/backups"

# Script de inicializacao do Memhack
export MEMHACK_SCRIPT='#!/system/bin/sh
PATH=/system/xbin:/usr/bin:/usr/sbin:/bin:/sbin:/system/sbin:/system/bin:/data/local/bin

if [ ! -d "/data/dalvik-cache" -o -L "/data/dalvik-cache" ]; then
	rm -f "/data/dalvik-cache"
	mkdir -p "/data/dalvik-cache"
	chown 1000.1000 "/data/dalvik-cache"
	chmod 771 "/data/dalvik-cache"
fi

if [ ! -d "/cache/dalvik-cache" -o -L "/cache/dalvik-cache" ]; then
	rm -f "/cache/dalvik-cache"
	mkdir -p "/cache/dalvik-cache"
	chown 1000.1000 "/cache/dalvik-cache"
	chmod 771 "/cache/dalvik-cache"
fi

if [ "$(df -k /cache | tail -n 1 | tr -s \  | cut -d \  -f 4)" -gt "10240" ]; then
	rm -f "/data/dalvik-cache/*"
	/system/xbin/mount -o "bind" "/cache/dalvik-cache" "/data/dalvik-cache"
fi
'

# Exibe o espaco livre nas particoes
function dfree () {
	df -h ${1} | tail -n 1 | tr -s ' ' | awk '{print $5 "\t" $3 "\t(" $4 " em uso)"}'
}


### Inicializacao ###

if [ ! -d "${MILETOOLS_ROOT}" ]; then
	# Primeira inicializacao do script, criar estrutura de diretorios
	mkdir "${MILETOOLS_ROOT}" || (echo "!!! Erro ao criar o diretorio principal !!!"; exit 1)
fi


### Processa as funcoes ###

case "${1}" in

	menu_root) # Menu principal
		echo "Milestone Tools" > "${MENU_FILE}"
		echo "Sair:menu:.." >> "${MENU_FILE}"

		## Exibe o espaco livre nas particoes
		echo "Espaco livre:break:*" >> "${MENU_FILE}"
		echo "$(dfree /cache):label:*" >> "${MENU_FILE}"
		echo "$(dfree /data):label:*" >> "${MENU_FILE}"
		echo "$(dfree /system):label:*" >> "${MENU_FILE}"

		## Submenus de configuracao
		echo "Submenus:break:*" >> "${MENU_FILE}"
		echo "[+] Backup:scripted_menu:miletools_backup.menu:${0} menu_backup" >> "${MENU_FILE}"
		echo "[+] Ajustar DPI da tela:scripted_menu:miletools_dpi.menu:${0} menu_dpi" >> "${MENU_FILE}"
		echo "[+] Selecionar Governor:scripted_menu:miletools_governor.menu:${0} menu_governor" >> "${MENU_FILE}"

		## Opcoes
		echo "Opcoes:break:*" >> "${MENU_FILE}"

		# Manter Home na memoria
		grep -q '^ro.HOME_APP_ADJ=1' '/system/build.prop' \
			&& echo "[X] Manter aplicativo Home sempre na memoria:shell:${0} root_homeinmem 0" >> "${MENU_FILE}" \
			|| echo "[ ] Manter aplicativo Home sempre na memoria:shell:${0} root_homeinmem 1" >> "${MENU_FILE}"

		# Mover Dalvik-Cache para /cache
		grep -q '^/system/xbin/memhack' '/system/bin/sh_hijack.sh' \
			&& echo "[X] Mover Dalvik-Cache para /cache:shell:${0} root_memhack 0" >> "${MENU_FILE}" \
			|| echo "[ ] Mover Dalvik-Cache para /cache:shell:${0} root_memhack 1" >> "${MENU_FILE}"

		# Problemas com DNS
		grep -Eq '^net\.(.*\.)?dns[12]=' '/system/build.prop' \
			&& echo "[X] Problemas com DNS:shell:${0} root_dnsfix 0" >> "${MENU_FILE}" \
			|| echo "[ ] Problemas com DNS:shell:${0} root_dnsfix 1" >> "${MENU_FILE}"

		# Remover OpenRecovery da galeria
		[ -f '/sdcard/OpenRecovery/.nomedia' ] \
			&& echo "[X] Remover OpenRecovery da Galeria de Imagens:shell:${0} root_oringal 0" >> "${MENU_FILE}" \
			|| echo "[ ] Remover OpenRecovery da Galeria de Imagens:shell:${0} root_oringal 1" >> "${MENU_FILE}"

		;;

	root_homeinmem) # Manter Home na memoria
		if [ "${2}" -eq '1' ]; then
			echo 'ro.HOME_APP_ADJ=1' >> '/system/build.prop'
		else
			sed -i '/^ro.HOME_APP_ADJ=1/d' '/system/build.prop'
		fi
		;;

	root_memhack) # Mover Dalvik-Cache para /cache
		if [ "${2}" -eq '1' ]; then
			echo "${MEMHACK_SCRIPT}" > '/system/xbin/memhack'
			chown 0.0 '/system/xbin/memhack'
			chmod 755 '/system/xbin/memhack'

			sed -i 's/exec \/system\/bin\/2nd-init/\/system\/xbin\/memhack\nexec \/system\/bin\/2nd-init/' '/system/bin/sh_hijack.sh'
		else
			rm -f '/system/xbin/memhack'

			sed -i '/^\/system\/xbin\/memhack/d' '/system/bin/sh_hijack.sh'
		fi
		;;

	root_dnsfix) # Problemas com DNS
		if [ "${2}" -eq '1' ]; then
			echo 'net.dns1=8.8.8.8' >> '/system/build.prop'
			echo 'net.dns2=8.8.4.4' >> '/system/build.prop'
			echo 'net.rmnet0.dns1=8.8.8.8' >> '/system/build.prop'
			echo 'net.rmnet0.dns2=8.8.4.4' >> '/system/build.prop'
		else
			sed -ri '/^net\.(.*\.)?dns[12]=/d' '/system/build.prop'
		fi
		;;

	root_oringal) # Remover OpenRecovery da Galeria
		if [ "${2}" -eq '1' ]; then
			touch '/sdcard/OpenRecovery/.nomedia'
		else
			rm -f '/sdcard/OpenRecovery/.nomedia'
		fi
		;;

	menu_backup) # Menu de Backup
		if [ ! -d "${MILETOOLS_BKPS}" ]; then
			mkdir "${MILETOOLS_BKPS}" || (echo "!!! Erro ao criar diretocio de backup !!!"; exit 1)
		fi

		echo "Backup" > "${MENU_FILE}"
		echo "Voltar:menu:.." >> "${MENU_FILE}"

		# build.prop
		echo "build.prop:break:*" >> "${MENU_FILE}"
		echo "Efetuar backup:shell:${0} backup_buildprop_backup" >> "${MENU_FILE}"
		echo "Restaurar backup:scripted_menu:miletools_backup_buildprop_restore.menu:${0} menu_backup_buildprop_restore" >> "${MENU_FILE}"

		# Aplicativos
		echo "Aplicativos:break:*" >> "${MENU_FILE}"
		echo "Efetuar backup:scripted_menu:miletools_backup_apps_backup.menu:${0} menu_backup_apps_backup" >> "${MENU_FILE}"
		echo "Restaurar backup:scripted_menu:miletools_backup_apps_restore.menu:${0} menu_backup_apps_restore" >> "${MENU_FILE}"
		;;

	backup_buildprop_backup) # Efetua backup do arquivo build.prop
		cp -f '/system/build.prop' "${MILETOOLS_BKPS}/build.prop_$(/system/xbin/date '+%Y%m%d%H%M')"
		;;

	menu_backup_buildprop_restore) # Menu de restauracao de build.prop
		echo "Restaurar arquivo build.prop" > "${MENU_FILE}"
		echo "Voltar:menu:.." >> "${MENU_FILE}"


		for BUILD_BACKUP in $(find ${MILETOOLS_BKPS} -name 'build.prop_*' | sort -r); do
			BUILD_BACKUP_DATE="$(echo ${BUILD_BACKUP} | cut -d'_' -f'2')"
			BUILD_BACKUP_NAME="$(/system/xbin/date -d ${BUILD_BACKUP_DATE} +'%d-%m-%Y %H.%M')"

			echo "${BUILD_BACKUP_NAME}:shell:${0} backup_buildprop_restore ${BUILD_BACKUP}" >> "${MENU_FILE}"
		done
		;;

	backup_buildprop_restore) # Restaura backup do arquivo build.prop
		cp -f "${2}" '/system/build.prop'
		chown 0.0 '/system/build.prop'
		chmod 644 '/system/build.prop'
		;;

	menu_backup_apps_backup) # Menu de backup de aplicativos
		echo "Backup de aplicativos" > "${MENU_FILE}"
		echo "Voltar:menu:.." >> "${MENU_FILE}"

		for APP_FOLDER in "/data/app" "/data/app-private" "/system/app"; do
			echo "${APP_FOLDER}:break:*" >> "${MENU_FILE}"
			for APP_FILE in $(find "${APP_FOLDER}" -name '*.apk'); do
				APP_NAME="$(basename ${APP_FILE} .apk)"
				echo "${APP_NAME}:shell:${0} backup_apps_backup ${APP_FILE}" >> "${MENU_FILE}"
			done
			echo "Voltar:menu:.." >> "${MENU_FILE}"
		done
		;;

	menu_backup_apps_restore) # Menu de restauracao de backup de aplicativos
		echo "Restaurar aplicativos" > "${MENU_FILE}"
		echo "Voltar:menu:.." >> "${MENU_FILE}"

		for APP_FOLDER in "/data/app" "/data/app-private" "/system/app"; do
			APP_PREFIX="$(echo app${APP_FOLDER} | sed -e 's/\//_/g')"
			
			echo "${APP_FOLDER}:break:*" >> "${MENU_FILE}"
			for APP_BACKUP in $(find ${MILETOOLS_BKPS} -name "${APP_PREFIX}_*.apk"); do
				APP_NAME=$(echo ${APP_BACKUP} | sed -e "s/.*\/${APP_PREFIX}_\(.*\).apk/\1/")

				echo "${APP_NAME}:shell:${0} backup_apps_restore ${APP_BACKUP}" >> "${MENU_FILE}"
			done
			echo "Voltar:menu:.." >> "${MENU_FILE}"
		done
		;;

	backup_apps_backup) # Efetua backup do aplictivo
		cp -f "${2}" "${MILETOOLS_BKPS}/app$(echo ${2} | sed -e 's/\//_/g')"
		;;

	backup_apps_restore) # Restaura os aplicativos
		APP_DEST="$(basename ${2} | cut -d'_' -f'2-' | sed -e 's/_/\//g')"

		cp -f "${2}" "${APP_DEST}"
		chown 1000.1000 "${APP_DEST}"
		chmod 644 "${APP_DEST}"
		;;

	menu_dpi) # Menu de ajuste de DPI
		echo "Ajuste de DPI da tela" > "${MENU_FILE}"
		echo "Voltar:menu:.." >> "${MENU_FILE}"

		for DPI_OPT in "180" "190 (Menor recomendavel)" "200 (Sugerido)" "210" "220" "230" "240 (Original)" "250" "260" "270" "280 (Maior recomendavel)" "290"; do
			DPI_VAL="$(echo ${DPI_OPT} | cut -d' ' -f1)"

			grep -q "^ro.sf.lcd_density=${DPI_VAL}" '/system/build.prop'\
				&& echo "[X] ${DPI_OPT}:shell:${0} dpi_set ${DPI_VAL}" >> "${MENU_FILE}" \
				|| echo "[ ] ${DPI_OPT}:shell:${0} dpi_set ${DPI_VAL}" >> "${MENU_FILE}"
		done
		;;

	dpi_set) # Ajusta a DPI da tela
		sed -i '/^ro.sf.lcd_density=/d' '/system/build.prop'
		echo "ro.sf.lcd_density=${2}" >> '/system/build.prop'
		;;

	menu_governor) # Menu de selecao de governor
		# Verifica o script
		if [ "$(head -n1 '/system/etc/init.d/72_governor')" != '#!/system/bin/sh' ]; then
			GOVERNOR_SCRIPT="$(</system/etc/init.d/72_governor)"
			echo -e '#!/system/bin/sh\n'"${GOVERNOR_SCRIPT}" > '/system/etc/init.d/72_governor'
		fi
		chown 0.0 '/system/etc/init.d/72_governor'
		chmod 755 '/system/etc/init.d/72_governor'

		# Monta o menu
		echo "Selecionar Governors" > "${MENU_FILE}"
		echo "Voltar:menu:.." >> "${MENU_FILE}"

		# Habilitar Governors
		echo "Governors habilitados:break:*" >> "${MENU_FILE}"
		for GOVERNOR_OPT in "stats (Estatisticas de Time-in-state)" "conservative (Maior economia)" "interactive (Maior performance)" "ondemand (Original)" "smartass (ShadowMOD-BR)"; do
			GOVERNOR_VAL="$(echo ${GOVERNOR_OPT} | cut -d' ' -f1)"

			grep -q "^insmod /system/lib/modules/cpufreq_${GOVERNOR_VAL}.ko" '/system/etc/init.d/72_governor' \
				&& echo "[X] ${GOVERNOR_OPT}:shell:${0} governor_enable 0 ${GOVERNOR_VAL}" >> "${MENU_FILE}" \
				|| echo "[ ] ${GOVERNOR_OPT}:shell:${0} governor_enable 1 ${GOVERNOR_VAL}" >> "${MENU_FILE}"
		done

		# Selecao de governor padrao
		echo "Governor padrao:break:*" >> "${MENU_FILE}"
		for GOVERNOR_OPT in "conservative" "interactive" "ondemand" "smartass"; do
			GOVERNOR_VAL="$(echo ${GOVERNOR_OPT} | cut -d' ' -f1)"

			grep -q "^echo .${GOVERNOR_VAL}. > .*/scaling_governor" '/system/etc/init.d/72_governor' \
				&& echo "[X] ${GOVERNOR_OPT}:shell:${0} governor_set ${GOVERNOR_VAL}" >> "${MENU_FILE}" \
				|| echo "[ ] ${GOVERNOR_OPT}:shell:${0} governor_set ${GOVERNOR_VAL}" >> "${MENU_FILE}"
		done
		;;

	governor_enable) # Habilita governor
		if [ "${2}" -eq '1' ]; then
			echo "insmod /system/lib/modules/cpufreq_${3}.ko" >> '/system/etc/init.d/72_governor'
		else
			sed -i "/^insmod .*\/cpufreq_${3}.ko/d" '/system/etc/init.d/72_governor'
		fi
		;;

	governor_set) # Define governor padrao
		# Verifica se o governor selecionado esta habilitado
		grep -q "^insmod \/system\/lib\/modules\/cpufreq_${2}.ko" ||
			echo "insmod /system/lib/modules/cpufreq_${2}.ko" >> '/system/etc/init.d/72_governor'

		sed -i '/^echo .* > .*\/scaling_governor/d' '/system/etc/init.d/72_governor'
		echo "echo '${2}' > '/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor'" >> '/system/etc/init.d/72_governor'
		;;

	*) # Inicializacao - Insere o Miletools no menu de aplicacoes
		echo "Milestone Tools 0.5:scripted_menu:miletools_root.menu:${0} menu_root" >> "${APP_MENU_FILE}"
		;;

esac